package com.dropdb.demo.service.impl;

import com.dropdb.demo.bean.*;
import com.dropdb.demo.bean.AdminGoodsPOJO;
import com.dropdb.demo.bean.bo.AdminListGoodsBO;
import com.dropdb.demo.bean.enumeration.ErrorReason;
import com.dropdb.demo.bean.vo.AdminBrandVO;
import com.dropdb.demo.bean.vo.AdminCateAndBrandVO;
import com.dropdb.demo.bean.vo.AdminCategoryVO;
import com.dropdb.demo.bean.vo.BaseData;
import com.dropdb.demo.mapper.*;
import com.dropdb.demo.service.GoodsService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
@Transactional
public class GoodsServiceImpl implements GoodsService {
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private GoodsSpecificationMapper goodsSpecificationMapper;
    @Autowired
    private GoodsAttributeMapper goodsAttributeMapper;
    @Autowired
    private GoodsProductMapper goodsProductMapper;
    @Autowired
    private GrouponRulesMapper grouponRulesMapper;

    /**
     * 分页获取所有的商品信息
     * @param listGoodsBO 接受前端参数
     * @return json
     */
    @Override
    public BaseData ListGoods(AdminListGoodsBO listGoodsBO) {
        GoodsExample goodsExample = new GoodsExample();
        // 排序
        goodsExample.setOrderByClause(listGoodsBO.getSort() + " " + listGoodsBO.getOrder());
        // 动态添加name和goodsSn条件
        GoodsExample.Criteria criteria = goodsExample.createCriteria();
        // 如果name不为空
        if (!StringUtils.isEmpty(listGoodsBO.getName())) {
            criteria.andNameLike("%" + listGoodsBO.getName() + "%");
        }
        // 如果goodsSn不为空
        if (!StringUtils.isEmpty(listGoodsBO.getGoodsSn())) {
            criteria.andGoodsSnEqualTo(listGoodsBO.getGoodsSn());
        }
        // 逻辑删除条件
        criteria.andDeletedEqualTo(false);
        // 添加分页
        PageHelper.startPage(listGoodsBO.getPage(), listGoodsBO.getLimit());
        List<Goods> goods = goodsMapper.selectByExampleWithBLOBs(goodsExample);
        PageInfo<Goods> pageInfo = new PageInfo<>(goods);
        long total = pageInfo.getTotal();
        return new BaseData(goods, total);
    }


    /**
     * 为上架商品提供类目和品牌信息
     * @return 规格类目和商品信息
     */
    @Override
    public AdminCateAndBrandVO ListCateAndBrand() {
        // 获取总的类目信息
        List<AdminCategoryVO> categoryList = categoryMapper.selectCateVOByPId(0);
        // 根据总类目id获取其子规格list
        for (AdminCategoryVO categoryVO : categoryList) {
            List<AdminCategoryVO> children = categoryMapper.selectCateVOByPId(categoryVO.getValue());
            categoryVO.setChildren(children);
        }
        // 获取所有的品牌信息
        List<AdminBrandVO> brandList = brandMapper.selectBrandVOList();
        AdminCateAndBrandVO cateAndBrandVO = new AdminCateAndBrandVO();
        cateAndBrandVO.setCategoryList(categoryList);
        cateAndBrandVO.setBrandList(brandList);
        return cateAndBrandVO;
    }

    /**
     * 上架商品
     * @param addGoodsBO
     * @return
     */
    @Override
    public ErrorReason addGoods(AdminGoodsPOJO addGoodsBO) {
        try {
            Date date = new Date();
            //添加商品
            Goods goods = addGoodsBO.getGoods();
            //当商品编号和商品名称重复时，不添加
            ErrorReason errorReason = isHasSameGoodsByNameOrGoodSn(goods);
            if (errorReason != null) return errorReason;
            //将商品信息补全
            //sortOrder不知道是啥
            //goods.setSortOrder();
            //添加时间
            goods.setAddTime(date);
            goods.setUpdateTime(date);
            goods.setDeleted(false);
            //插入
            goodsMapper.insert(goods);
            //获取商品id
            Integer goodsId = goods.getId();
            //添加商品规格
            List<GoodsSpecification> specifications = addGoodsBO.getSpecifications();
            for (GoodsSpecification specification : specifications) {
                insertSpecification(date, goodsId, specification);
            }
            //添加商品参数
            List<GoodsAttribute> attributes = addGoodsBO.getAttributes();
            for (GoodsAttribute attribute : attributes) {
                insertAttribute(date, goodsId, attribute);
            }
            //添加商品库存
            List<GoodsProduct> products = addGoodsBO.getProducts();
            for (GoodsProduct product : products) {
                insertProduct(date, goodsId, product);
            }
        } catch (Exception e) {
            // 如果出现异常
            e.printStackTrace();
            return ErrorReason.INTERNAL_ERROR;
        }
        return ErrorReason.SUCESS;
    }

    public ErrorReason isHasSameGoodsByNameOrGoodSn(Goods goods) {
        //当商品编号和商品名称重复时，不添加
        GoodsExample goodsExample1 = new GoodsExample();
        GoodsExample.Criteria criteria1 = goodsExample1.createCriteria();
        criteria1.andGoodsSnEqualTo(goods.getGoodsSn());
        if (goods.getId() != null) {
            criteria1.andIdNotEqualTo(goods.getId());
        }
        List<Goods> sameGoodsSn = goodsMapper.selectByExample(goodsExample1);
        if (!sameGoodsSn.isEmpty()) {
            return ErrorReason.GOODSN_SAME;
        }
        GoodsExample goodsExample2 = new GoodsExample();
        GoodsExample.Criteria criteria2 = goodsExample2.createCriteria();
        criteria2.andNameEqualTo(goods.getName());
        if (goods.getId() != null) {
            criteria2.andIdNotEqualTo(goods.getId());
        }
        List<Goods> sameGoodsName = goodsMapper.selectByExample(goodsExample2);
        if (!sameGoodsName.isEmpty()) {
            return ErrorReason.GOODSNAME_SAME;
        }
        return null;
    }

    /**
     * 插入库存信息
     * @param date
     * @param goodsId
     * @param product
     */
    public void insertProduct(Date date, Integer goodsId, GoodsProduct product) {
        //商品库存信息补全
        //设置是否删除
        product.setId(null);
        product.setDeleted(false);
        //商品id
        product.setGoodsId(goodsId);
        //添加时间
        product.setAddTime(date);
        product.setUpdateTime(date);
        goodsProductMapper.insert(product);
    }

    /**
     * 插入参数信息
     * @param date
     * @param goodsId
     * @param attribute
     */
    public void insertAttribute(Date date, Integer goodsId, GoodsAttribute attribute) {
        //参数信息补全
        //商品id
        attribute.setGoodsId(goodsId);
        //添加时间
        attribute.setAddTime(date);
        attribute.setUpdateTime(date);
        //设置是否删除
        attribute.setDeleted(false);
        goodsAttributeMapper.insert(attribute);
    }

    /**
     * 插入规格信息
     * @param date
     * @param goodsId
     * @param specification
     */
    public void insertSpecification(Date date, Integer goodsId, GoodsSpecification specification) {
        //规格信息补全
        //商品id
        specification.setGoodsId(goodsId);
        //设置是否删除
        specification.setDeleted(false);
        //添加时间
        specification.setAddTime(date);
        specification.setUpdateTime(date);
        goodsSpecificationMapper.insert(specification);
    }


    /**
     * 获取商品详细信息
     * @param id
     * @return
     */
    @Override
    public AdminGoodsPOJO getGoodsDetailById(Integer id) {
        AdminGoodsPOJO goodsVO = new AdminGoodsPOJO();
        // 获取商品基本信息
        Goods goods = goodsMapper.selectByPrimaryKey(id);
        goodsVO.setGoods(goods);
        // 如果商品不存在表示，该商品已删除
        if (goods == null) return null;
        // 查询该商品大类目和小类目
        Integer categoryId = goods.getCategoryId();
        // 根据小类别查大类别
        Category subCategory = categoryMapper.selectByPrimaryKey(categoryId);
        // 装入bean
        Integer[] categoryIds = null;
        if (subCategory != null) {
            categoryIds = new Integer[]{subCategory.getPid(), categoryId};
        }
        goodsVO.setCategoryIds(categoryIds);
        // 利用商品id查询商品参数
        List<GoodsAttribute> goodsAttributes = getGoodsAttributes(id);
        goodsVO.setAttributes(goodsAttributes);
        // 利用商品id查询规格信息
        List<GoodsSpecification> specifications = getGoodsSpecifications(id);
        goodsVO.setSpecifications(specifications);
        // 利用商品id查询库存信息
        List<GoodsProduct> products = getGoodsProducts(id);
        goodsVO.setProducts(products);
        return goodsVO;
    }

    /**
     * 根据商品id获取规格信息
     * @param id
     * @return
     */
    public List<GoodsSpecification> getGoodsSpecifications(Integer id) {
        GoodsSpecificationExample specificationExample = new GoodsSpecificationExample();
        specificationExample.createCriteria().andGoodsIdEqualTo(id);
        return goodsSpecificationMapper.selectByExample(specificationExample);
    }


    /**
     * 根据商品id获取库存信息
     * @param id
     * @return
     */
    public List<GoodsProduct> getGoodsProducts(Integer id) {
        GoodsProductExample productExample = new GoodsProductExample();
        productExample.createCriteria().andGoodsIdEqualTo(id);
        return goodsProductMapper.selectByExample(productExample);
    }

    /**
     * 根据商品id获取所有参数信息
     * @param id
     * @return
     */
    public List<GoodsAttribute> getGoodsAttributes(Integer id) {
        GoodsAttributeExample attributeExample = new GoodsAttributeExample();
        attributeExample.createCriteria().andGoodsIdEqualTo(id);
        return goodsAttributeMapper.selectByExample(attributeExample);
    }

    /**
     * 更新商品
     * @param updateGoodsBO
     * @return
     */
    @Override
    public ErrorReason updateGoods(AdminGoodsPOJO updateGoodsBO) {
        Goods goods = updateGoodsBO.getGoods();
        //当商品编号和商品名称重复时，不更新
        ErrorReason errorReason = isHasSameGoodsByNameOrGoodSn(goods);
        if (errorReason != null) return errorReason;

        /**
         * goods表
         */
        Date date = new Date();
        // 更新goods
        goods.setUpdateTime(date);
        // 获取商品id
        Integer goodsId = goods.getId();
        goodsMapper.updateByPrimaryKeySelective(goods);

        /**
         * Specification表
         */
        // 观察前端页面发现当商品规格发生变化时，会删除原来的所有库存信息
        // 会根据新的product数组添加新的数据
        // 因此要定义一个变量记录规格是否发生修改
        boolean specModify = false;
        // 前端的页面实际上只提供了规格的添加和删除
        // 根据updateGoodsBO的规格信息进行对比
        // 如果库中和BO中都存在就将其从库中spec的list中删除
        // 最后如果有剩余就是将要删除的spec
        // 添加的spec其BO中id为null
        // 根据goodsId获取所有规格信息
        List<GoodsSpecification> specs = getGoodsSpecifications(goodsId);
        List<GoodsSpecification> updateSpecs = updateGoodsBO.getSpecifications();
        for (GoodsSpecification updateSpec : updateSpecs) {
            if (updateSpec.getId() != null) {
                for (GoodsSpecification spec : specs) {
                    if (updateSpec.getId().equals(spec.getId())) {
                        specs.remove(spec);
                        break;
                    }
                }
            } else {
                // id为null说明可以添加
                insertSpecification(date, goodsId, updateSpec);
                // 规格信息发生添加
                specModify = true;
            }
        }
        // 判断specs最后是否为空，不为空说明有规格已被删除
        if (!specs.isEmpty()) {
            specModify = true;
            for (GoodsSpecification spec : specs) {
                goodsSpecificationMapper.deleteByPrimaryKey(spec.getId());
            }
        }

        /**
         * product表
         */
        // 根据goodsId获取所有库存信息
        List<GoodsProduct> products = updateGoodsBO.getProducts();
        // 如果规格发生修改，删除该商品所有规格
        // 然后添加新的库存信息
        if (specModify) {
            // 删除
            GoodsProductExample goodsProductExample = new GoodsProductExample();
            goodsProductExample.createCriteria().andGoodsIdEqualTo(goodsId);
            goodsProductMapper.deleteByExample(goodsProductExample);
            // 添加
            for (GoodsProduct product : products) {
                insertProduct(date, goodsId, product);
            }
        } else {
            // 如果规格未发生变化，则更新
            for (GoodsProduct product : products) {
                product.setUpdateTime(date);
                goodsProductMapper.updateByPrimaryKeySelective(product);
            }
        }


        /**
         * attribute表
         */
        // attribute也只能添加或者删除
        // 还是和spec同样的套路
        // 获取库中数据
        List<GoodsAttribute> attributes = getGoodsAttributes(goodsId);
        // 获取BO中数据
        List<GoodsAttribute> updateAttributes = updateGoodsBO.getAttributes();
        for (GoodsAttribute updateAttribute : updateAttributes) {
            if (updateAttribute.getId() != null) {
                // 此时检查有哪些attribute应该删除
                for (GoodsAttribute attribute : attributes) {
                    if (updateAttribute.getId().equals(attribute.getId())) {
                        attributes.remove(attribute);
                        break;
                    }
                }
            } else {
                // id未null说明时新插入的数据
                insertAttribute(date, goodsId, updateAttribute);
            }
        }
        // 如果此时attributes不为空说明，有参数应该被删除
        if (!attributes.isEmpty()) {
            for (GoodsAttribute attribute : attributes) {
                goodsAttributeMapper.deleteByPrimaryKey(attribute.getId());
            }
        }
        return ErrorReason.SUCESS;
    }


    /**
     * 删除商品
     * 逻辑删除
     * @param goods
     */
    /*@Override
    public void deleteGoods(Goods goods) {
        Integer goodsId = goods.getId();
        // goods表
        goods.setDeleted(true);
        goodsMapper.updateByPrimaryKeyWithBLOBs(goods);
        // spec表
        GoodsSpecification specification = new GoodsSpecification();
        specification.setDeleted(true);
        GoodsSpecificationExample specificationExample = new GoodsSpecificationExample();
        specificationExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsSpecificationMapper.updateByExampleSelective(specification, specificationExample);
        // product表
        GoodsProduct product = new GoodsProduct();
        product.setDeleted(true);
        GoodsProductExample productExample = new GoodsProductExample();
        productExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsProductMapper.updateByExampleSelective(product, productExample);
        // attribute表
        GoodsAttribute attribute = new GoodsAttribute();
        attribute.setDeleted(true);
        GoodsAttributeExample attributeExample = new GoodsAttributeExample();
        attributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsAttributeMapper.updateByExampleSelective(attribute, attributeExample);
    }*/


    /**
     * 删除商品
     * 物理删除
     * @param goods
     */
    @Override
    public void deleteGoods(Goods goods) {
        Integer goodsId = goods.getId();
        // goods表
        goodsMapper.deleteByPrimaryKey(goodsId);
        // spec表
        GoodsSpecificationExample specificationExample = new GoodsSpecificationExample();
        specificationExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsSpecificationMapper.deleteByExample(specificationExample);
        // product表
        GoodsProductExample productExample = new GoodsProductExample();
        productExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsProductMapper.deleteByExample(productExample);
        // attribute表
        GoodsAttributeExample attributeExample = new GoodsAttributeExample();
        attributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        goodsAttributeMapper.deleteByExample(attributeExample);
        // groupon_rules表
        GrouponRulesExample grouponRulesExample = new GrouponRulesExample();
        grouponRulesExample.createCriteria().andGoodsIdEqualTo(goodsId);
        grouponRulesMapper.deleteByExample(grouponRulesExample);
    }

}
